<?php
/**
 * Created by PhpStorm.
 * User: stupboy
 * Date: 2018/4/14
 * Time: 9:54
 * Mail:87658989@qq.com
 */

namespace app\cron\logic;

use app\api\logic as apilogic;
use app\cron\model\Driver;
use think\Db;

class Disptach
{

    /**
     * 执行派单
     * @param array $orders
     */
    public function dispatchOrder($orders = [])
    {
        foreach ($orders as $order) {
            $this->selectDispatchWay($order);
        }
    }

    /**
     * 派单方式过滤
     * @param $order
     */
    public function selectDispatchWay($order)
    {
        // 续单派单,原司机未派单成功则进入正常派单
        if ($order['reorder'] > 0) {
            if ($this->dispatchReOrder($order)) return;
        }
        // 自有车辆派单
        if($order['pay_type']==4){
            return;
        }
        // 四办订单不走派单
        $propArr = explode(',',$order['prop']);
        if (in_array(13,$propArr) && $order['order_type'] == 1) {
            $this->dispatchLeaderCar($order);
            return;
        };
        // 行政执法订单
        if ($order['use_type'] == 1) {
            $this->dispatchLawCar($order);
            return;
        }
        // 社会和单位订单
        if ($order['order_type'] == 3 || $order['order_type'] == 2 || $order['pay_type']==2 || $order['pay_type']==1) {
            $this->dispatchSocietyCar($order);
            return;
        }
        // 公务订单
        if ($order['order_type'] == 1) {
            $ret = $this->dispatchOfficeCar($order, 5000);
            // 5公里未派车成功则执行10公里派车
            !$ret && $this->dispatchOfficeCar($order, 10000);
            return;
        }
    }

    /**
     * 订单派车
     * @param $order array 订单
     * @param $lonMin float 最小经度
     * @param $lonMax float 最大经度
     * @param $latMin float 最小纬度
     * @param $latMax float 最大纬度
     * @param $carType int 车型
     * @param $type int 类型
     * @param $limit int 种类
     * @return bool
     */
    public function dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $carType, $type, $limit = 0)
    {
        $driverModel = new Driver();
        list($drivers, $driversSpare) = $driverModel->getNearDriverByGpsRedis($order, $lonMin, $lonMax, $latMin, $latMax, $carType, $type, $limit);
        if (empty($drivers) && empty($driversSpare)) {
            return false;
        }
        // 派单结果默认false
        $ret = false;
        // 根据司机距离进行循环派单
        foreach ($drivers as $driver) {
            list($code,) = (new apilogic\Driver())->receiveOrder($driver['driver_id'], $order['order_id']);
            // 派单成功跳出循环
            if ($code == 1) {
                $ret = true;
                break;
            }
        }
        if ($ret) return true;
        // 备选车型派单
        foreach ($driversSpare as $driver) {
            list($code,) = (new apilogic\Driver())->receiveOrder($driver['driver_id'], $order['order_id'], $driver['rece_car']);
            // 派单成功跳出循环
            if ($code == 1) {
                $ret = true;
                break;
            }
        }
        return $ret;
    }

    /**
     * 续单派车
     * @param $order
     * @return bool
     */
    public function dispatchReOrder($order)
    {
        $oldOrder = Db::name('order')->find($order['reorder']);
        list($code,) = (new apilogic\Driver())->receiveOrder($oldOrder['driver_id'], $order['order_id'], $oldOrder['car_id']);
        return $code == 1 ? true : false;
    }

    /**
     * 社会及单位订单派单
     * @param $order
     * @param int $radius
     */
    public function dispatchSocietyCar($order, $radius = 5000)
    {
        // 获取经纬度范围
        list($lonMin, $lonMax, $latMin, $latMax) = getAround($order['from_lon'], $order['from_lat'], $radius);
        $carType = $order['car_type'];
        // 公务车强制转换
        $order['type'] == 2 && $order['type'] = 4;
        $order['type'] == 3 && $order['type'] = 5;
        $type = $this->changeType($order['type']);// 2 3 4 5
        // 车型全部匹配派单
        $ret = $this->dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $carType, $type);
        // 升级车型派
        $upArr = [
            2 => [3, 4, 9],// 优选 升 舒适 豪华 商务
            3 => [4, 9],// 舒适 升 豪华 商务
            4 => [9]// 豪华 升 商务
        ];
        if ($ret) return;
        $upTypes = $upArr[$carType];
        foreach ($upTypes as $upType) {
            $ret = $this->dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $upType, $type);
            if ($ret) break;
        }
    }

    /**
     * 四办派车
     * @param $order
     * @return bool
     */
    public function dispatchLeaderCar($order)
    {
        $carType = $order['car_type'];
        $type = $order['type'];
        return $this->dispatchCar($order, 0, 180, 0, 180, $carType, $type, 3);
    }

    /**
     * 行政执法派车
     * @param $order
     * @return bool
     */
    public function dispatchLawCar($order)
    {
        $carType = $order['car_type'];
        $type = $order['type'];
        return $this->dispatchCar($order, 0, 180, 0, 180, $carType, $type, 2);
    }

    /**
     * 公务派车
     * @param $order
     * @param int $radius
     * @return bool
     */
    public function dispatchOfficeCar($order, $radius = 5000)
    {
        // 获取经纬度范围
        list($lonMin, $lonMax, $latMin, $latMax) = getAround($order['from_lon'], $order['from_lat'], $radius);
        $carType = $order['car_type'];
        $type = $this->changeType($order['type']);
        // 车型全部匹配派单
        $ret = $this->dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $carType, $type);
        if ($ret) return true;
        // 升级车型派
        $upArr = [
            2 => [3, 4, 9],// 优选 升 舒适 豪华 商务
            3 => [4, 9],// 舒适 升 豪华 商务
            4 => [9]// 豪华 升 商务
        ];
        $upTypes = $upArr[$carType];
        foreach ($upTypes as $upType) {
            $ret = $this->dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $upType, $type);
            if ($ret) break;
        }
        if ($ret) return true;
        return false;//注释本行则进行公务订单跳转社会车
        // 没有公务车则进行社会车辆派单
        $type = 4;
        // 车型全部匹配派单
        $ret = $this->dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $carType, $type);
        if ($ret) return true;
        // 社会同级车辆无法满足条件情况下，升级社会车辆
        $upTypes = $upArr[$carType];
        foreach ($upTypes as $upType) {
            $ret = $this->dispatchCar($order, $lonMin, $lonMax, $latMin, $latMax, $upType, $type);
            if ($ret) break;
        }
        if ($ret) return true;
        return false;
    }

    public function dispatchOtherCar($order)
    {

    }

    /**
     * 包车车型转化普通车型进行派单
     * @param $type
     * @return int
     */
    public function changeType($type)
    {
        if ($type == 3) {
            return 2;
        }
        if ($type == 5) {
            return 4;
        }
        return $type;
    }
}